package com.xdtech.hotel.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xdtech.common.utils.ApplicationContextUtil;
import com.xdtech.common.utils.JsonUtil;
import com.xdtech.core.dao.BaseDao;
import com.xdtech.core.model.BaseItem;
import com.xdtech.core.orm.Page;
import com.xdtech.core.orm.utils.BeanUtils;
import com.xdtech.hotel.dao.DeviceEventDao;
import com.xdtech.hotel.model.DeviceEvent;
import com.xdtech.hotel.monitor.RoomMonitorInfo;
import com.xdtech.hotel.protocol.manager.OperationManager;
import com.xdtech.hotel.protocol.manager.RoomMonitor;
import com.xdtech.hotel.protocol.util.WiegandUtils;
import com.xdtech.hotel.protocol.vo.Ac;
import com.xdtech.hotel.protocol.vo.Card;
import com.xdtech.hotel.protocol.vo.CmdNode;
import com.xdtech.hotel.protocol.vo.Dimmer;
import com.xdtech.hotel.protocol.vo.Fault;
import com.xdtech.hotel.protocol.vo.Music;
import com.xdtech.hotel.protocol.vo.RoomPanelStatus;
import com.xdtech.hotel.protocol.vo.Scene;
import com.xdtech.hotel.protocol.vo.Tv;
import com.xdtech.hotel.service.CardService;
import com.xdtech.hotel.service.DeviceEventService;
import com.xdtech.hotel.service.DeviceService;
import com.xdtech.hotel.service.RoomService;
import com.xdtech.hotel.service.TestDataService;
import com.xdtech.hotel.util.HotelConstants;
import com.xdtech.hotel.util.RoomContants;
import com.xdtech.hotel.vo.DeviceEventItem;
import com.xdtech.hotel.vo.RoomItem;
import com.xdtech.web.model.Pagination;

/**
 * 
 * @author max.zheng
 * @create 2015-05-05 22:31:28
 * @since 1.0
 * @see
 */
@Service
public class DeviceEventServiceImpl implements DeviceEventService {
	@Autowired
	private DeviceEventDao deviceEventDao;
	@Autowired
	private BaseDao baseDao;

	@Autowired
	private DeviceService deviceService;
	@Autowired
	private RoomService roomService;
	@Autowired
	private CardService cardService;
	
	private Log log = LogFactory.getLog(DeviceEventServiceImpl.class);
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param entity
	 */
	public void save(DeviceEvent entity) {
		deviceEventDao.save(entity);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param entity
	 */
	public void saveAll(List<DeviceEvent> entities) {
		deviceEventDao.saveAll(entities);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param entity
	 */
	public void delete(DeviceEvent entity) {
		deviceEventDao.delete(entity);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param id
	 */
	public void delete(Long id) {
		deviceEventDao.delete(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param id
	 * @return
	 */
	public DeviceEvent get(Long id) {
		return deviceEventDao.get(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @return
	 */
	public List<DeviceEvent> getAll() {
		return deviceEventDao.getAll();
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param pg
	 * @param values
	 * @return
	 */
	public Map<String, Object> loadPageAndCondition(Pagination pg,
			Map<String, String> values) {
		Map<String, Object> results = new HashMap<String, Object>();
		List<Object> deviceEvents = null;
		long rows = 0;
		if (pg!=null) {
			Page<DeviceEvent> page = deviceEventDao.findPage(pg,"from DeviceEvent order by createTime desc", values);
			deviceEvents = BeanUtils.copyListProperties(
					DeviceEventItem.class, page.getResult());
			rows = page.getTotalItems();
		}else {
			List<DeviceEvent> deviceEventList = deviceEventDao.find("from DeviceEvent order by id desc", values);
			deviceEvents = BeanUtils.copyListProperties(
					DeviceEventItem.class, deviceEventList);
			rows = deviceEvents.size();
		}
		results.put("total", rows);
		results.put("rows", deviceEvents);
		return results;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param item
	 * @return
	 */
	public boolean saveOrUpdateDeviceEvent(DeviceEventItem item) {
		DeviceEvent deviceEvent = null;
		if (item.getId()==null) {
			deviceEvent = new DeviceEvent();
		}else {
			deviceEvent = deviceEventDao.get(item.getId());
		}
		//复制前台修改的属性
		BeanUtils.copyProperties(deviceEvent, item);
		deviceEventDao.save(deviceEvent);
		return true;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param deviceEventId
	 * @return
	 */
	public DeviceEventItem loadDeviceEventItem(Long deviceEventId) {
		DeviceEvent deviceEvent = deviceEventDao.get(deviceEventId);
		DeviceEventItem deviceEventItem = new DeviceEventItem();
		BeanUtils.copyProperties(deviceEventItem, deviceEvent);
		return deviceEventItem;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param id
	 * @return
	 */
	public boolean deleteDeviceEventInfo(long id) {
		delete(id);
		return true;
	}
	
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @param newIds
	 * @return
	 */
	public boolean deleteDeviceEventInfo(List<Long> deviceEventIds) {
		for (Long id : deviceEventIds) {
			delete(id);
		}
		return true;
	}
	
	public Map<String, Object> loadPageDataByConditions(Pagination pg,
			BaseItem baseItem, String queryName) {
		Map<String, Object> results = new HashMap<String, Object>();
		Page page = baseDao.findPageByNamedQuery(pg, queryName,baseItem);
		results.put("total", page.getTotalItems());
		results.put("rows", page.getResult());
		return results;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-05 22:31:28
	 * @modified by
	 * @return
	 */
	@Override
	public List<DeviceEventItem> loadItems() {
		List<DeviceEvent> deviceEvents = getAll();
		return DeviceEventItem.createItems(deviceEvents);
	}

	/**
	 * 
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-5-5 下午12:40:31
	 * @param postContent
	 */
	public void handlPostData(String postContent)
	{
		try
		{
			org.codehaus.jettison.json.JSONObject json = new org.codehaus.jettison.json.JSONObject(postContent);
			final String sn = json.getString("SN");
			//测试写死
//			if ("{\"SN\":\"123456789\",\"commit\":[{\"node\":[{\"addr\":\"6\",\"channel\":\"13\",\"status\":\"on\",\"freq\":\"0\",\"delay\":\"0\"}]}]}".equals(postContent))
//			{
//				//发送返回数据；
//				//{"SN": "5760611", "write": [{"node": [ {"addr": "1","channel": "1","delay": "1","freq": "1","status": "blink"},{"addr": "2","channel": "1","delay": "1","freq": "1","status": "blink"}]}]}
//				String cmdData = "{\"SN\": \"123456789\", \"write\": [{\"node\": [ {\"addr\": \"1\",\"channel\": \"1\",\"delay\": \"1\",\"freq\": \"1\",\"status\": \"blink\"},{\"addr\": \"2\",\"channel\": \"1\",\"delay\": \"1\",\"freq\": \"1\",\"status\": \"blink\"}]}]}";
//				OperationManager.sendWriteCmdToDev(sn, null, cmdData);
//				return;
//			}
			//自定义测试定义
			TestDataService testDataService = (TestDataService) ApplicationContextUtil.getContext().getBean("testDataServiceImpl");
			final String returnData = testDataService.getReturnData(postContent);
			if (StringUtils.isEmpty(returnData))
			{
				RoomItem roomItem = deviceService.getDeviceLinkRoomBySn(sn);
				if (null != roomItem)
				{
					JSONArray jsonArray = json.getJSONArray("commit");
					for (int i = 0; i < jsonArray.length(); i++)
					{
						JSONObject jsonContent = jsonArray.getJSONObject(i);
//						roomItem.updateComponentInfo(jsonContent);
						updateComponentInfo(roomItem,jsonContent);
					}
					//信息变更，更新监控数据
					RoomMonitor.updateMonitorRoomInfo(roomItem);
					//是否考虑同步数据库？
					roomService.saveOrUpdateRoom(roomItem);
					
				}
			}else
			{
//				new Thread(new Runnable() {
//					
//					@Override
//					public void run() {
						OperationManager.sendCmdToDev(sn, returnData);
						log.info("自定义数据返回："+returnData);
//					}
//				}).start();
				
			}
			
			
			
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * 根据设备上传数据，变更roomItem关联信息，同时记录事件信息
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-5-6 上午11:15:20
	 * @param roomItem
	 * @param jsonContent
	 * @throws Exception
	 */
	private void updateComponentInfo(RoomItem roomItem,JSONObject jsonContent) throws Exception
	{
		
		JSONArray componentArray = null;
		if (jsonContent.has(HotelConstants.DEV_NODE_CONTROL))
		{
			//节点
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_NODE_CONTROL);
//			[{"addr":"6","channel":"13","status":"on","freq":"0","delay":"0"}]
			List<CmdNode> nodes = JsonUtil.getDTOList(componentArray.toString(), CmdNode.class);
			for (CmdNode node : nodes)
			{
				if (roomItem.updateNode(node))
				{
					saveDeviceEventInfo(roomItem,HotelConstants.DEV_NODE_CONTROL,JsonUtil.getJsonStr(node));
				}
			}

		}
		else if (jsonContent.has(HotelConstants.DEV_AC_CONTROL))
		{
			//空调
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_AC_CONTROL);
			List<Ac> acs = JsonUtil.getDTOList(componentArray.toString(), Ac.class);
			for (Ac ac : acs)
			{
				if (roomItem.updateAc(ac))
				{
					saveDeviceEventInfo(roomItem,HotelConstants.DEV_AC_CONTROL,JsonUtil.getJsonStr(ac));
				}
			}

		}
		else if (jsonContent.has(HotelConstants.DEV_DIMMER_CONTROL))
		{
			//灯光
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_DIMMER_CONTROL);
			List<Dimmer> dimmers = JsonUtil.getDTOList(componentArray.toString(), Dimmer.class);
			for (Dimmer dimmer : dimmers)
			{
				if (roomItem.updateDimmer(dimmer))
				{
					saveDeviceEventInfo(roomItem,HotelConstants.DEV_DIMMER_CONTROL,JsonUtil.getJsonStr(dimmer));
				}
			}
		}
		else if (jsonContent.has(HotelConstants.DEV_TV_CONTROL))
		{
			//电视
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_TV_CONTROL);
			List<Tv> tvs = JsonUtil.getDTOList(componentArray.toString(), Tv.class);
			for (Tv tv : tvs)
			{
				if (roomItem.updateTv(tv))
				{
					saveDeviceEventInfo(roomItem,HotelConstants.DEV_TV_CONTROL,JsonUtil.getJsonStr(tv));
				}
			}

		}
		else if (jsonContent.has(HotelConstants.DEV_MUSIC_CONTROL))
		{
			//音乐
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_MUSIC_CONTROL);
			List<Music> musics = JsonUtil.getDTOList(componentArray.toString(), Music.class);
			for (Music music : musics)
			{
				if (roomItem.updateMusic(music))
				{
					saveDeviceEventInfo(roomItem,HotelConstants.DEV_MUSIC_CONTROL,JsonUtil.getJsonStr(music));
				}
			}

		}
		else if (jsonContent.has(HotelConstants.DEV_SCENE_CONTROL))
		{
			//场景
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_SCENE_CONTROL);
			List<Scene> scenes = JsonUtil.getDTOList(componentArray.toString(), Scene.class);
			for (Scene scene : scenes)
			{
				if (roomItem.updateScene(scene))
				{
					saveDeviceEventInfo(roomItem,HotelConstants.DEV_SCENE_CONTROL,JsonUtil.getJsonStr(scene));
				}
			}
		}
		else if (jsonContent.has(HotelConstants.DEV_CARD_CONTROL))
		{
			//卡
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_CARD_CONTROL);
			List<Card> cards = JsonUtil.getDTOList(componentArray.toString(), Card.class);
			for (Card card : cards)
			{
				if(roomItem.updateCard(card)) {
					saveDeviceEventInfoWithCard(roomItem,HotelConstants.DEV_CARD_CONTROL,card);
				}
			}
		}else if (jsonContent.has(HotelConstants.DEV_POST_FAULT_FLAG))
		{
			//故障
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_POST_FAULT_FLAG);
			List<Fault> faults = JsonUtil.getDTOList(componentArray.toString(), Fault.class);
			for (Fault fault : faults)
			{
				if (roomItem.addFault(fault))
				{
					saveDeviceEventInfoWithFault(roomItem,HotelConstants.DEV_POST_FAULT_FLAG,fault);
				}
			}
			
		}else if (jsonContent.has(HotelConstants.DEV_POST_ROOM_FLAG))
		{
			//房见面板操作
			componentArray = jsonContent.getJSONArray(HotelConstants.DEV_POST_ROOM_FLAG);
			List<RoomPanelStatus> roomStatus = JsonUtil.getDTOList(componentArray.toString(), RoomPanelStatus.class);
			for (RoomPanelStatus rs : roomStatus)
			{
				if (roomItem.updateRoomStatus(rs))
				{
					saveDeviceEventInfoWithPanelOperation(roomItem,HotelConstants.DEV_POST_ROOM_FLAG,rs);
				}
			}
		}

	}
	/**
	 * 
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-5-7 下午1:46:50
	 * @param roomItem
	 * @param devPostRoomFlag
	 * @param rs
	 */
	private void saveDeviceEventInfoWithPanelOperation(RoomItem roomItem, String devPostRoomFlag, RoomPanelStatus rs)
	{
		DeviceEvent deviceEvent = new DeviceEvent(roomItem.getDeviceSn(),devPostRoomFlag,JsonUtil.getJsonStr(rs));
		RoomMonitorInfo roomMonitorInfo = RoomMonitor.monitorDatas.get(roomItem.getRoomNo());
		deviceEvent.setEventOperator(roomMonitorInfo.getCustomer());
		deviceEvent.setEventDesc(RoomContants.roomPanelOperation.get(rs.getNumber()));
		deviceEvent.setEventName(RoomContants.roomPanelOperation.get(rs.getNumber()));
		save(deviceEvent);
	}
	/**
	 * 故障信息处理
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-5-7 下午1:41:20
	 * @param roomItem
	 * @param devPostFaultFlag
	 * @param fault
	 */
	private void saveDeviceEventInfoWithFault(RoomItem roomItem, String devPostFaultFlag, Fault fault)
	{
		DeviceEvent deviceEvent = new DeviceEvent(roomItem.getDeviceSn(),devPostFaultFlag,JsonUtil.getJsonStr(fault));
		RoomMonitorInfo roomMonitorInfo = RoomMonitor.monitorDatas.get(roomItem.getRoomNo());
		deviceEvent.setEventOperator(roomMonitorInfo.getCustomer());
		save(deviceEvent);
	}
	/**
	 * 
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-5-7 上午11:15:17
	 * @param roomItem
	 * @param devCardControl
	 * @param card
	 */
	private void saveDeviceEventInfoWithCard(RoomItem roomItem, String devCardControl, Card card)
	{
		DeviceEvent deviceEvent = new DeviceEvent(roomItem.getDeviceSn(),devCardControl,JsonUtil.getJsonStr(card));
		String eventName = card.getStatus().equals("on")?"插卡动作":"拔卡动作";
		deviceEvent.setEventName(eventName);
		String cardNo = WiegandUtils.getCardByWg26(card.getData());
		deviceEvent.setOperationContent(cardNo);
		com.xdtech.hotel.model.Card card2 = cardService.getCardByNo(cardNo);
		//设置卡的类型说明
		deviceEvent.setEventDesc(card2.getCardType());
		RoomMonitorInfo roomMonitorInfo = RoomMonitor.monitorDatas.get(roomItem.getRoomNo());
		deviceEvent.setEventOperator(roomMonitorInfo.getCustomer());
		save(deviceEvent);
	}
	/**
	 * 
	 * @author <a href="max.zheng@zkteco.com">郑志雄</>
	 * @since 2015-5-6 上午11:37:03
	 * @param roomItem
	 * @param devTvControl
	 * @param jsonStr
	 */
	private void saveDeviceEventInfo(RoomItem roomItem, String controlType, String jsonStr)
	{
		DeviceEvent deviceEvent = new DeviceEvent(roomItem.getDeviceSn(),controlType,jsonStr);
		RoomMonitorInfo roomMonitorInfo = RoomMonitor.monitorDatas.get(roomItem.getRoomNo());
		deviceEvent.setEventOperator(roomMonitorInfo.getCustomer());
		save(deviceEvent);
//		roomItem.setScene(scene)
	}

}
